perm filename PIX.SAI[PIX,HPM]9 blob sn#159964 filedate 1975-05-21 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00029 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00004 00002	BEGIN "PIX"
C00006 00003	      IF CHR=("?" LAND '137) THEN
C00009 00004	      IF CHR="T" THEN comment take a picture via a camera
C00010 00005	      IF CHR=(" " LAND '137) THEN comment take a picture via a camera
C00012 00006	      IF CHR>("0" LAND '137) ∧ CHR≤("9" LAND '137)
C00015 00007	      IF CHR='135 THEN	comment  alter camera number
C00016 00008	      IF CHR="B" THEN	comment  alter bits/pixel
C00017 00009	      IF CHR="I" THEN	comment  input a file
C00019 00010	      IF CHR="O" THEN	comment  output a file
C00020 00011	      IF CHR="D" THEN	comment  video synthesizer display
C00022 00012	      IF CHR="H" THEN	comment  high quality halftone
C00024 00013	      IF CHR="R" THEN	comment  random halftone
C00026 00014	      IF CHR="A" THEN	comment  arty bug halftone
C00028 00015	      IF CHR="C" THEN	comment  step past a certain number of pictures
C00029 00016	      IF CHR="S" THEN	comment  change size of displays
C00033 00017	      IF CHR="F" THEN	comment  high pass filter
C00034 00018	      IF CHR="L" THEN	comment  low pass filter
C00035 00019	      IF CHR="Z" THEN	comment  select a piece
C00037 00020	      IF CHR="N" THEN	comment  apply noise remover
C00038 00021	      IF CHR="V" THEN	comment  apply interest operator
C00039 00022	      IF CHR="P" THEN	comment  pixel transform
C00041 00023	      IF CHR="G" THEN	comment  graph a histogram
C00044 00024	      IF CHR="J" THEN	comment  graph a histogram
C00047 00025	      IF CHR="E" THEN	comment  apply histogram normalizer
C00048 00026	      IF CHR="Y" THEN	comment  apply vert sync loss correction
C00049 00027	      IF CHR="Q" THEN	comment  exit
C00050 00028	         BEGIN       comment  an unrecognized character
C00052 00029	      END
C00055 ENDMK
C⊗;
BEGIN "PIX"
REQUIRE "VIXNIC.SAI[VIS,HPM]" SOURCE_FILE;
REQUIRE "WIXNIC.SAI[VIS,HPM]" SOURCE_FILE;

INTEGER CAMERA,CHR,HIG,WID,BITS,PWANT,PHAVE,PDEFAULT;
STRING BACKLOG;    REAL SSIZE,HSIZE,SASPECT,HASPECT;
INTEGER SDISWID,SDISHIG,SYPOS;
INTEGER HDISWID,HDISHIG,HAPOS;
BOOLEAN INITED,SYNLAS;

CAMERA←'54; BACKLOG←""; INITED←FALSE; SYNLAS←TRUE;

HIG←262; WID←300; BITS←4;
SSIZE←HSIZE←.5; SASPECT←HASPECT←7/9;
SDISWID←HDISWID←SDISHIG←HDISHIG←1; HAPOS←SYPOS←1;
PDEFAULT←PWANT←PHAVE←PIXDIM(HIG,WID,BITS);

DDINIT;
SCREEN(-1,-1,1,1); DRKEN; RECTAN(-1000,-1000,1000,1000);

OUTSTR("? FOR HELP (this is a new PIX)"&'15&'12);

WHILE TRUE DO
   BEGIN
   INTEGER ARRAY PIC[0:PHAVE];

   IF PHAVE=PDEFAULT THEN 
      BEGIN
      MAKPIX(HIG,WID,BITS,PIC[0]);
      INITED←TRUE;
      END;

   WHILE PHAVE=PWANT DO
      BEGIN
      IF LENGTH(BACKLOG)=0 THEN
         BEGIN
         OUTSTR("*");
         DO CHR←INCHRW LAND '137 UNTIL CHR≠'15;
         END
      ELSE CHR←LOP(BACKLOG) LAND '137;
      IF CHR=("?" LAND '137) THEN
         BEGIN
         OUTSTR("TYPE

""T"" to take a picture from currently selected source
<space> to take a picture and output it to a file
<n> (any number) to take n pictures and write them out automatically

<altmode> to change video source (44, the cart receiver, is the default)
""B"" to change number of bits per sample from the cameras. default=4

""I"" to read a picture from a file
""O"" to output the latest picture to a file

""D"" to display the current picture on the video synthesizer
""H"" to display it as a high quality halftone
""R"" for a low quality random halftone
""A"" for a halftone with an arty bug
""C"" skip past a number of slots (when displaying multiple pictures)

""S"" subdivisions and size of the displays. Initially 1 by 1 and 1/2 size.

""F"" high pass filter the current picture
""L"" reduce the current picture to half resolution
""Z"" select a portion of the picture
""N"" apply a noise removing operator
""V"" apply a directional variance interest operator
""P"" transform the picture (permute pixel values) according to a table
""G"" graph the number of occurrences of each grey level value
""J"" graph the number of pixels less than each grey level
""E"" enhance a picture (normalize the number of occurrences of each grey level)
""Y"" fix a picture that has lost vertical sync (rolled in the y direction)

""Q"" quit
");
         END
      ELSE
      IF CHR="T" THEN comment take a picture via a camera;
         BEGIN
         IF PHAVE=PDEFAULT THEN
            BEGIN
            IF ¬INITED THEN
               BEGIN
               MAKPIX(HIG,WID,BITS,PIC[0]);
               INITED←TRUE;
               END;
            CAMPIX(CAMERA,0,2,IF BITS=4 THEN 1 ELSE 2,
               IF BITS=4 THEN 8 ELSE IF BITS=7 THEN 1 ELSE 2,PIC[0]);
            OUTSTR('15&'12);
            END
         ELSE
            BEGIN
            BACKLOG←"T";
            PWANT←PDEFAULT;
            END;
         END
      ELSE
      IF CHR=(" " LAND '137) THEN comment take a picture via a camera;
         BEGIN
         IF PHAVE=PDEFAULT THEN
            BEGIN
            CAMPIX(CAMERA,0,2,IF BITS=4 THEN 1 ELSE 2,
               IF BITS=4 THEN 8 ELSE IF BITS=7 THEN 1 ELSE 2,PIC[0]);
            OUTSTR('15&'12);
            BACKLOG←"O";
            END
         ELSE
            BEGIN
            BACKLOG←"TO";
            PWANT←PDEFAULT;
            END;
         END
      ELSE
      IF CHR>("0" LAND '137) ∧ CHR≤("9" LAND '137)
      THEN comment take a series of pictures;
         BEGIN
         IF PHAVE=PDEFAULT THEN
            BEGIN
            INTEGER MAX,I,J,HR,MIN,SEC; STRING FN,FN1;
            MAX←CHR LAND '17;
            FOR I←1 STEP 1 UNTIL MAX DO
               BEGIN
               CAMPIX(CAMERA,0,2,IF BITS=4 THEN 1 ELSE 2,
                  IF BITS=4 THEN 8 ELSE IF BITS=7 THEN 1 ELSE 2,PIC[0]);
               SETFORMAT(2,0);
               HR←CALL(0,"TIMER")%60;
               SEC←HR MOD 60;
               HR←HR%60;
               MIN←HR MOD 60;
               HR←HR%60;
               FN1←CVS(HR)&CVS(MIN)&CVS(SEC);
               FN←"";
               FOR J←1 STEP 1 UNTIL 6 DO
                  FN←FN&(IF FN1[J TO J]=" " THEN "0" ELSE FN1[J TO J]);
               FN←FN&".PIC";
               PUTPFL(PIC[0],FN);
               OUTSTR("	"&FN&" WRITTEN"&'15&'12);
               IF I<3∧LENGTH(BACKLOG)=0 THEN
                  BEGIN
                  IF (J←INCHRS)>0 THEN
                     BEGIN
                     IF J≥"0"∧J≤"9" THEN MAX←10*MAX+(J LAND '17)
                     ELSE BACKLOG←J;
                     END;
                  END;
               END;
            END
         ELSE
            BEGIN
            BACKLOG←CHR;
            PWANT←PDEFAULT;
            END;
         END
      ELSE
      IF CHR='135 THEN	comment  alter camera number;
         BEGIN
         OUTSTR(" CHANNEL NUMBER:");
         CAMERA←CVO(INCHWL);
         END
      ELSE
      IF CHR="B" THEN	comment  alter bits/pixel;
         BEGIN
         OUTSTR(" BITS/PIXEL (4 to 7):");
         BITS←(CVD(INCHWL) MAX 4) MIN 7;
         PDEFAULT←PWANT←PIXDIM(HIG,WID,BITS);
         END
      ELSE
      IF CHR="I" THEN	comment  input a file;
         BEGIN
         STRING FN;
         IF LENGTH(BACKLOG)=0 THEN
            BEGIN
            OUTSTR("FILE:");
            IF LENGTH(FN←INCHWL)>0 ∧ PFLDIM(FN)>0 THEN
                BEGIN
                PWANT←PFLDIM(FN);
                BACKLOG←"I"&FN;
                END ELSE OUTSTR("aborted"&'15&'12);
            END
         ELSE
            BEGIN
            GETPFL(BACKLOG,PIC[0]);
            BACKLOG←"";
            INITED←FALSE;
            END;
         END
      ELSE
      IF CHR="O" THEN	comment  output a file;
         BEGIN
         STRING FN;
         OUTSTR("FILE:");
         IF LENGTH(FN←INCHWL)≠0 THEN PUTPFL(PIC[0],FN)
         ELSE OUTSTR("aborted"&'15&'12);
         END
      ELSE
      IF CHR="D" THEN	comment  video synthesizer display;
         BEGIN
         INTEGER I,J;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←TRUE;

         MODP←SYPOS MOD (SDISWID*SDISHIG);
         PX←MODP MOD SDISWID;
         MODP←MODP%SDISWID;
         PY←SDISHIG-MODP-1;
         PX←2*PX-SDISWID+1;
         PY←2*PY-SDISHIG+1;

         SX←1; SY←1; ASPEN←SASPECT*SDISWID/SDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*SSIZE;  SY←SY*SSIZE;

         SCREEN(-SDISWID,-SDISHIG,SDISWID,SDISHIG);
         FOR I←5 STEP -1 UNTIL (6-PIC[BYBI]) MAX 0 DO
            BEGIN
            IF SDISHIG*SDISWID>1 THEN GETDDF("DD"&CVS(I)&".TMP[TMP,HPM]");
            DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
            VID(PX-SX,PY-SY,PX+SX,PY+SY,PIC[0],2↑(PIC[BYBI]+I-6));
            FOR J←1,1,1,1,1,1 DO DPYUP(SYNMAP(I));
            SHOWA('47);
            IF SDISHIG*SDISWID>1 THEN PUTDDF("DD"&CVS(I)&".TMP[TMP,HPM]");
            END;
         SYPOS←SYPOS+1;
         OUTSTR('15&'12&"*");
         SHOW('47);
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         END
      ELSE
      IF CHR="H" THEN	comment  high quality halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VIDEO(PX-SX,PY-SY,PX+SX,PY+SY,PIC[0],-2);
         CHN←GDDCHN(-1);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         SHOW(CHN);
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="R" THEN	comment  random halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VID(PX-SX,PY-SY,PX+SX,PY+SY,PIC[0],-1);
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         SHOW(CHN);
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="A" THEN	comment  arty bug halftone;
         BEGIN
         INTEGER J,CHN;
         REAL SX,SY,ASP,ASPEN;
         REAL PX,PY; INTEGER MODP;

         SYNLAS←FALSE;

         MODP←HAPOS MOD (HDISWID*HDISHIG);
         PX←MODP MOD HDISWID;
         MODP←MODP%HDISWID;
         PY←HDISHIG-MODP-1;
         PX←2*PX-HDISWID+1;
         PY←2*PY-HDISHIG+1;

         SX←1; SY←1; ASPEN←HASPECT*HDISWID/HDISHIG;
         ASP←PIC[PCLN]/PIC[LNBY];
         IF ASP>ASPEN THEN SX←ASPEN/ASP ELSE SY←ASP/ASPEN;

         SX←SX*HSIZE; SY←SY*HSIZE;

         SCREEN(-HDISWID,-HDISHIG,HDISWID,HDISHIG);
         IF HDISHIG*HDISWID>1 THEN GETDDF("DD.TMP[TMP,HPM]");
         DRKEN; RECTAN(PX-1,PY-1,PX+1,PY+1);
         VIDEO(PX-SX,PY-SY,PX+SX,PY+SY,PIC[0],-4);
         CHN←GDDCHN(-1);
         FOR J←1,1,1,1,1,1 DO DPYUP(CHN);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         SHOW(CHN);
         IF HDISHIG*HDISWID>1 THEN PUTDDF("DD.TMP[TMP,HPM]");
         HAPOS←HAPOS+1;
         OUTSTR("*");
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         SHOW(-1);
         RDDCHN(CHN);
         END
      ELSE
      IF CHR="C" THEN	comment  step past a certain number of pictures;
         BEGIN
         INTEGER T;
         OUTSTR("SKIP HOW MANY (NEGATIVE TO BACKSPACE):");
         T←CVD(INCHWL);
         IF SYNLAS THEN SYPOS←SYPOS+T ELSE HAPOS←HAPOS+T;
         END
      ELSE
      IF CHR="S" THEN	comment  change size of displays;
         BEGIN
         STRING INP; INTEGER FOO,T,INC;
         OUTSTR('15&'12&"FOR SYNTHESIZER OR HALFTONES (S OR H)?"); 
         INC←INCHWL LAND '137;
         IF INC="S" THEN
            BEGIN
            INTEGER I;
            SETFORMAT(0,2);
            OUTSTR("PICTURE SIZE (1 IS FULLSIZE, NOW"&CVF(SSIZE)&"):"); INP←INCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN SSIZE←ABS(T);
            OUTSTR("ASPECT RATIO (HEIGHT/WIDTH OF SCREEN, NOW"&CVF(SASPECT)&"):");
            INP←INCHWL;
            T←REALSCAN(INP,FOO);
            IF T>0 THEN SASPECT←T;
            OUTSTR("NUMBER OF PICTURES IN X DIRECTION:"); 
            T←ABS(CVD(INCHWL));
            IF T>0∧T≠SDISWID THEN
               BEGIN
               SDISWID←T;
               SYPOS←0;
               END;
            OUTSTR("NUMBER OF PICTURES IN Y DIRECTION:"); 
            T←ABS(CVD(INCHWL));
            IF T>0∧T≠SDISHIG THEN
               BEGIN
               SDISHIG←T;
               SYPOS←0;
               END;
            SCREEN(-1,-1,1,1);
            DRKEN; RECTAN(-1000,-1000,1000,1000);
            IF SDISHIG*SDISWID>1 THEN
               BEGIN
               OUTSTR("ERASE?");
               IF (INCHWL LAND '137)="Y" THEN
               FOR I←0 STEP 1 UNTIL 5 DO
                  PUTDDF("DD"&CVS(I)&".TMP[TMP,HPM]");
               END;
            END
         ELSE IF INC="H" THEN
            BEGIN
            SETFORMAT(0,2);
            OUTSTR("PICTURE SIZE (1 IS FULLSIZE, NOW"&CVF(HSIZE)&"):"); INP←INCHWL;
            T←REALSCAN(INP,FOO);
            IF T≠0 THEN HSIZE←ABS(T);
            OUTSTR("ASPECT RATIO (HEIGHT/WIDTH OF SCREEN, NOW"&CVF(HASPECT)&"):");
            INP←INCHWL;
            T←REALSCAN(INP,FOO);
            IF T>0 THEN HASPECT←T;
            OUTSTR("NUMBER OF PICTURES IN X DIRECTION:"); 
            T←ABS(CVD(INCHWL));
            IF T>0∧T≠HDISWID THEN
               BEGIN
               HDISWID←T;
               HAPOS←0;
               END;
            OUTSTR("NUMBER OF PICTURES IN Y DIRECTION:"); 
            T←ABS(CVD(INCHWL));
            IF T>0∧T≠HDISHIG THEN
               BEGIN
               HDISHIG←T;
               HAPOS←0;
               END;
            SCREEN(-1,-1,1,1);
            DRKEN; RECTAN(-1000,-1000,1000,1000);
            IF HDISHIG*HDISWID>1 THEN PUTDDF("DD.TMP[TMP,HPM]");
            END;
         END
      ELSE
      IF CHR="F" THEN	comment  high pass filter;
         BEGIN
         INTEGER ARRAY T[0:PHAVE];
         INTEGER WINDOW;
         DO
            BEGIN
            OUTSTR(" WINDOW SIZE:");
            WINDOW←CVD(INCHWL);
            END
         UNTIL WINDOW>1 ∧ WINDOW <40;
         PASSHI(PIC[0],WINDOW,T[0]);
         NORMALIZE(T[0]);
         COPPIC(T[0],PIC[0]);
         END
      ELSE
      IF CHR="L" THEN	comment  low pass filter;
         BEGIN
         INTEGER ARRAY T[0:PHAVE];
         IF PIC[PCLN]≥2∧PIC[LNBY]≥2 THEN
            BEGIN
            HAFPIC(PIC[0],T[0],6);
            COPPIC(T[0],PIC[0]);
            END;
         PWANT←PHAVE←PIXDIM(PIC[PCLN],PIC[LNBY],PIC[BYBI]);
         INITED←FALSE;
         OUTSTR('15&'12);
         END
      ELSE
      IF CHR="Z" THEN	comment  select a piece;
         BEGIN
         INTEGER XL,XH,YL,YH,FOO;
         STRING INFL;

         OUTSTR('15&'12);
         OUTSTR("LOW X, HIGH X (0 TO 1):"); INFL←INCHWL;
         XL←REALSCAN(INFL,FOO)*PIC[LNBY];
         XH←REALSCAN(INFL,FOO)*PIC[LNBY];
         IF XL>XH THEN XL↔XH;
         XL←XL MAX 0; XH←XH MIN (PIC[LNBY]-1);

         OUTSTR("LOW Y, HIGH Y (0 TO 1):"); INFL←INCHWL;
         YL←REALSCAN(INFL,FOO)*PIC[PCLN];
         YH←REALSCAN(INFL,FOO)*PIC[PCLN];
         IF YL>YH THEN YL↔YH;
         YL←YL MAX 0; YH←YH MIN (PIC[PCLN]-1);

            BEGIN
            INTEGER ARRAY T[0:PIXDIM(YH-YL+1,XH-XL+1,PIC[BYBI])];
            MAKPIX(YH-YL+1,XH-XL+1,PIC[BYBI],T[0]);
            SELECT(PIC[0],YL,XL,T[0]);
            COPPIC(T[0],PIC[0]);
            PWANT←PHAVE←PIXDIM(PIC[PCLN],PIC[LNBY],PIC[BYBI]);
            INITED←FALSE;
            END;

         END
      ELSE
      IF CHR="N" THEN	comment  apply noise remover;
         BEGIN
         CLEAN(PIC[0]);
         OUTSTR('15&'12);
         END
      ELSE
      IF CHR="V" THEN	comment  apply interest operator;
         BEGIN
         INTEGER WINDOW;
         DO
            BEGIN
            OUTSTR(" WINDOW SIZE:"); WINDOW←CVD(INCHWL);
            END UNTIL WINDOW≥1 ∧ WINDOW≤40;
         INTEREST(PIC[0],WINDOW,PIC[0]);
         END
      ELSE
      IF CHR="P" THEN	comment  pixel transform;
         BEGIN
         PRELOAD_WITH -1;
         OWN INTEGER ARRAY PERM[0:1024];
         STRING INP; INTEGER FOO,I,J;
         INTEGER LAST,THIS;

         IF PERM[0]≥0∧INITED THEN
            BEGIN
            OUTSTR(" ENTER NEW TRANSFORM?");
            INP←(INCHRW LAND '137);
            END ELSE INP←"Y";
         OUTSTR('15&'12);
         IF INP="Y" THEN
            BEGIN
            INITED←TRUE;
            OUTSTR(CVS(2↑PIC[BYBI])&" TOTAL GREY LEVELS, ENTER HOW MANY:");
            FOO←(CVD(INCHWL) MAX 2) MIN 2↑PIC[BYBI];
            LAST←0;
            FOR I←0 STEP 1 UNTIL FOO-1 DO
               BEGIN
               THIS←((1 ASH PIC[BYBI])-1)*I%(FOO-1);
               OUTSTR(CVS(THIS)&"→");
               PERM[THIS]←CVD(INCHWL);
               IF THIS>LAST THEN
               FOR J←LAST STEP 1 UNTIL THIS DO
                  PERM[J]←(PERM[LAST]*(THIS-J)+PERM[THIS]*(J-LAST))%(THIS-LAST);
               LAST←THIS;
               END;
            FOR I←0 STEP 1 UNTIL 2↑PIC[BYBI]-1 DO
               PERM[I]←(PERM[I] MAX 0) MIN (2↑PIC[BYBI]-1);
            END;
         PERBIT(PIC[0],PERM[0]);
         END
      ELSE
      IF CHR="G" THEN	comment  graph a histogram;
         BEGIN
         INTEGER ARRAY HIST[0:2↑PIC[BYBI]];
         INTEGER FOO,I,J,MAV,CHN;
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         FOO←2↑PIC[BYBI]-1;
         HISTOG(PIC[0],HIST[0]);
         SCREEN(-.3,-.2,1.1,1.2);
         DRKEN; RECTAN(-100,-1000,1000,1000);
         LITEN;
         LINE(0,0,0,1); LINE(0,1,1,1);
         LINE(1,1,1,0); LINE(1,0,0,0);
         LINE(0,.5,1,.5); LINE(0,.25,1,.25); LINE(0,.75,1,.75);
         LINE(.5,0,.5,1); LINE(.25,0,.25,1); LINE(.75,0,.75,1);
         MAV←0; FOR I←0 STEP 1 UNTIL FOO DO MAV←MAV MAX HIST[I];
         MAV←MAV+1;
         FOR I←1 STEP 1 UNTIL FOO DO
            LINE((I-1)/FOO,HIST[I-1]/MAV,I/FOO,HIST[I]/MAV);
         TXTPOS(0,-1/10,1/24,1/12); TEXT("0");
         TXTPOS(1-LENGTH(CVS(2↑PIC[BYBI]))/24,-1/10,1/24,1/12);
         TEXT(CVS(2↑PIC[BYBI]-1));
         TXTPOS(-.07,0,1/24,1/12); TEXT("0");
         TXTPOS(-.07-(LENGTH(CVS(MAV))-1)/24,1-1/12,1/24,1/12); TEXT(CVS(MAV));
         FOR J←1,1,1,1,1 DO DPYUP(CHN);
         SHOW(CHN);
         OUTSTR("*");
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         RDDCHN(CHN);
         SHOW(-1);
         DRKEN; RECTAN(-1000,-1000,1000,1000);
         END
      ELSE
      IF CHR="J" THEN	comment  graph a histogram;
         BEGIN
         INTEGER ARRAY HIST[0:2↑PIC[BYBI]];
         INTEGER FOO,I,J,L,MAV,CHN;
         CHN←GDDCHN(-1);
         OUTSTR(" CHANNEL "&CVOS(CHN)&'15&'12);
         FOO←2↑PIC[BYBI]-1;
         HISTOG(PIC[0],HIST[0]);
         SCREEN(-.3,-.2,1.1,1.2);
         DRKEN; RECTAN(-100,-1000,1000,1000);
         LITEN;
         LINE(0,0,0,1); LINE(0,1,1,1);
         LINE(1,1,1,0); LINE(1,0,0,0);
         LINE(0,.5,1,.5); LINE(0,.25,1,.25); LINE(0,.75,1,.75);
         LINE(.5,0,.5,1); LINE(.25,0,.25,1); LINE(.75,0,.75,1);
         MAV←0; FOR I←0 STEP 1 UNTIL FOO DO MAV←MAV + HIST[I];
         L←J←0;
         FOR I←1 STEP 1 UNTIL FOO DO
            BEGIN
            L←J;
            J←J+HIST[I];
            LINE((I-1)/FOO,L/MAV,I/FOO,J/MAV);
            END;
         TXTPOS(0,-1/10,1/24,1/12); TEXT("0");
         TXTPOS(1-LENGTH(CVS(2↑PIC[BYBI]))/24,-1/10,1/24,1/12);
         TEXT(CVS(2↑PIC[BYBI]-1));
         TXTPOS(-.07,0,1/24,1/12); TEXT("0");
         TXTPOS(-.07-(LENGTH(CVS(MAV))-1)/24,1-1/12,1/24,1/12); TEXT(CVS(MAV));
         FOR J←1,1,1,1,1 DO DPYUP(CHN);
         SHOW(CHN);
         OUTSTR("*");
         DO BACKLOG←INCHRW UNTIL BACKLOG≠'15∧BACKLOG≠'12;
         RDDCHN(CHN);
         SHOW(-1);
         DRKEN; RECTAN(-1000,-1000,1000,1000);
         END
      ELSE
      IF CHR="E" THEN	comment  apply histogram normalizer;
         BEGIN
         NORMALIZE(PIC[0]);
         OUTSTR('15&'12);
         END
      ELSE
      IF CHR="Y" THEN	comment  apply vert sync loss correction;
         BEGIN
         SYNCHRONIZE(PIC[0]);
         OUTSTR('15&'12);
         END
      ELSE
      IF CHR="Q" THEN	comment  exit;
         BEGIN
         CALL(0,"EXIT");
         END
      ELSE
         BEGIN       comment  an unrecognized character;
         IF CHR='12 THEN OUTSTR('15) ELSE
         OUTSTR("?"&'15&'12);
         END;
      END;
   PHAVE←PWANT;
   END;
END;